package org.hackystat.ui.projectviewer.gwt.client.common.types;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hackystat.ui.projectviewer.gwt.client.common.ProjectViewerException;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * Envelope which encloses all project information for easy transfer.
 *
 * @author Pavel Senin.
 *
 */
public class ProjectData implements IsSerializable {
  private String description;
  private Date startTime;
  private Date endTime;
  private String owner;
  private List<String> members;
  private List<String> uriPatterns;
  private Map<String, String> properties;
  private Date lastMod;
  private String name;
  private List<String> invitations;

  private static final String TRA = "<tr>";
  private static final String TRAGREY = "<tr bgcolor=\"#CCCCCC\">";
  private static final String TDGREY = "<td bgcolor=\"#CCCCCC\">";
  // private static final String TDWHITE = "<td bgcolor=\"#000000\">";
  private static final String TRB = "</tr>";
  private static final String TDA = "<td>";
  private static final String TDB = "</td>";
  private static final String TDSPAN = "<td colspan=\"2\">";

  /**
   * Constructor.
   */
  public ProjectData() {
    this.name = "Changeme";
    this.description = "";
    this.startTime = new Date();
    this.endTime = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 360);
    this.owner = "";
    this.members = new ArrayList<String>();
    this.uriPatterns = new ArrayList<String>();
    this.properties = new HashMap<String, String>();
    this.lastMod = new Date();
    this.invitations = new ArrayList<String>();
  }

  /**
   * Get project name.
   *
   * @return The project name.
   */
  public String getName() {
    return this.name;
  }

  /**
   * Set the project name.
   *
   * @param name The project name.
   * @throws ProjectViewerException if null value provided.
   */
  public void setName(String name) throws ProjectViewerException {
    if (null == name || 0 == name.length()) {
      throw new ProjectViewerException("Unable create project with the NULL name!");
    }
    else {
      this.name = name;
    }
  }

  /**
   * Get project description.
   *
   * @return The project description.
   */
  public String getDescription() {
    return this.description;
  }

  /**
   * Sets project description.
   *
   * @param desc The project description.
   */
  public void setDescription(String desc) {
    if (null == desc) {
      this.description = "";
    }
    else {
      this.description = desc;
    }
  }

  /**
   * Get project owner.
   *
   * @return The project owner.
   */
  public String getOwner() {
    return this.owner;
  }

  /**
   * Set project owner.
   *
   * @param owner The project owner.
   * @throws ProjectViewerException if null or empty string provided.
   */
  public void setOwner(String owner) throws ProjectViewerException {
    if (null == owner || owner.length() == 0) {
      throw new ProjectViewerException("Unable to set owner to NULL!");
    }
    else {
      this.owner = owner;
    }
  }

  /**
   * Reports project start time.
   *
   * @return The project start time.
   */
  public Date getStartTime() {
    return this.startTime;
  }

  /**
   * Sets the project start time.
   *
   * @param startTime The project start time.
   */
  public void setStartTime(Date startTime) {
    if (null == startTime) {
      this.startTime = new Date(System.currentTimeMillis());
    }
    else {
      this.startTime = startTime;
    }
  }

  /**
   * Reports project end time.
   *
   * @return The project end time.
   */
  public Date getEndTime() {
    return this.endTime;
  }

  /**
   * Sets project end time.
   *
   * @param endTime The end time to set.
   */
  public void setEndTime(Date endTime) {
    if (null == endTime) {
      this.endTime = new Date(System.currentTimeMillis() + 100 * 60 * 60 * 24 * 360);
    }
    else {
      this.endTime = endTime;
    }
  }

  /**
   * Reports last project modification time.
   *
   * @return The project last modification time.
   */
  public Date getLastMod() {
    return this.lastMod;
  }

  /**
   * Set last modification time.
   *
   * @param lastMod The project last modification time.
   */
  public void setLastMod(Date lastMod) {
    this.lastMod = lastMod;
  }

  /**
   * Reports members of the project.
   *
   * @return the project members.
   */
  public List<String> getMembers() {
    return this.members;
  }

  /**
   * Set members of the project.
   *
   * @param members The project members.
   */
  public void setMembers(List<String> members) {
    if (null == members) {
      this.members = new ArrayList<String>();
    }
    else {
      this.members = members;
    }
  }

  /**
   * Reports uri patterns of the project.
   *
   * @return The uri patterns of the project.
   */
  public List<String> getUriPatterns() {
    return this.uriPatterns;
  }

  /**
   * Set uri patterns of the project.
   *
   * @param uriPatterns The project uri patterns.
   */
  public void setUriPatterns(List<String> uriPatterns) {
    if (null == uriPatterns) {
      this.uriPatterns = new ArrayList<String>();
    }
    else {
      this.uriPatterns = uriPatterns;
    }
  }

  /**
   * Reports properties of the project.
   *
   * @return The properties of the project.
   */
  public Map<String, String> getProperties() {
    return this.properties;
  }

  /**
   * Set properties of the project.
   *
   * @param properties The project properties.
   */
  public void setProperties(Map<String, String> properties) {
    if (null == properties) {
      this.properties = new HashMap<String, String>();
    }
    else {
      this.properties = properties;
    }
  }

  /**
   * Converts this object to HTML.
   *
   * @return HTML.
   */
  public String toHTML() {
    DateTimeFormat dtf1 = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    StringBuffer sb = new StringBuffer(5000);
    // sb.append("<h2>" + this.name + "</h2>" + "<table width=\"100%\" >");
    // sb.append(TRA);
    // sb.append(TDA + "Description:" + TDB + TDA + this.description + TDB);
    sb.append("<table width=\"100%\" >");
    sb.append(TDA + "Description:" + TDB + TDA + this.description + TDB);
    sb.append(TRB + TRAGREY);
    sb.append(TDA + "Owner:" + TDB + TDA + this.owner + TDB);
    sb.append(TRB + TRA);
    sb.append(TDA + "Started:" + TDB + TDA + dtf1.format(this.startTime) + TDB);
    sb.append(TRB + TRAGREY);
    sb.append(TDA + "Ended:" + TDB + TDA + dtf1.format(this.endTime) + TDB);
    sb.append(TRB + TRA);
    sb.append(TDA + "Modified:" + TDB + TDA + dtf1.format(this.lastMod) + TDB);

    sb.append(TRB + TRAGREY);
    sb.append(TDSPAN + "Project members:" + TDB + TRB + TRA);
    for (int i = 0; i < this.members.size(); i++) {
      sb.append(TDA + TDB + TDGREY + this.members.get(i) + TDB);
      sb.append(TRB + TRA);
    }

    sb.append(TRB + TRA);
    sb.append(TDSPAN + "Project URI's:" + TDB + TRB + TRA);
    for (int i = 0; i < this.uriPatterns.size(); i++) {
      sb.append(TDA + TDB + TDA + this.uriPatterns.get(i) + TDB);
      sb.append(TRB + TRA);
    }

    sb.append(TRB + TRAGREY);
    sb.append(TDSPAN + "Project Properties:" + TDB + TRB + TRA);
    if (null != this.properties) {
      sb.append(TDA + TDB + TDA + "<table width=\"100%\" cellspacing=\"1\">" + TRA);
      Iterator<String> itr = this.properties.keySet().iterator();
      while (itr.hasNext()) {
        String key = (String) itr.next();
        sb.append(TRA + TDGREY + key + TDB + TDGREY + this.properties.get(key) + TDB + TRB);
      }

      sb.append("</table> " + TDB);
    }

    sb.append(TRB + TRA);
    sb.append(TDSPAN + "Project invitations:" + TDB + TRB + TRA);
    for (int i = 0; i < this.invitations.size(); i++) {
      sb.append(TDA + TDB + TDGREY + this.invitations.get(i) + TDB);
      sb.append(TRB + TRA);
    }

    sb.append("</table>");
    return sb.toString();
  }

  /**
   * Sets project start date.
   *
   * @param startDate The start date to set.
   */
  public void setStartTime(String startDate) {
    DateTimeFormat dtf = DateTimeFormat.getFormat("MM/dd/yy");
    if (null == startDate || 0 == startDate.length()) {
      this.startTime = new Date(System.currentTimeMillis());
    }
    else {
      this.startTime = dtf.parse(startDate);
    }
  }

  /**
   * Sets project end date.
   *
   * @param endDate The end date to set.
   */
  public void setEndTime(String endDate) {
    DateTimeFormat dtf = DateTimeFormat.getFormat("MM/dd/yy");
    if (null == endDate || 0 == endDate.length()) {
      this.endTime = new Date(System.currentTimeMillis());
      this.endTime.setYear(this.endTime.getYear() + 1);
    }
    else {
      this.endTime = dtf.parse(endDate);
    }
  }

  /**
   * Set e-mail invitations for the project.
   *
   * @param invitation The list of members invited.
   */
  public void setInvitations(List<String> invitation) {
    this.invitations = invitation;
  }

  /**
   * Reports list of invited members for this project.
   *
   * @return list of invited members for this project.
   */
  public List<String> getInvitations() {
    return this.invitations;
  }
}
